#include "DEV_Config.h"
#include "EPD.h"
#include "GUI_Paint.h"
#include "imagedata.h"
#include "page_manager.h"
#include "mqtt_handler.h"
#include "network_api.h"
#include "business_clock_page.h"

// 页面类型定义
#define BUSINESS_CLOCK_PAGE 1  // 如果page_manager.h中没有定义的话

// 更新间隔设置
const unsigned long WEATHER_UPDATE_INTERVAL = 12 * 60 * 60 * 1000; // 12小时更新一次
const unsigned long TIME_UPDATE_INTERVAL = 60 * 1000; // 每分钟更新一次时间
const unsigned long FULL_REFRESH_INTERVAL = 24 * 60 * 60 * 1000; // 每天全屏刷新一次防止残影
const unsigned long WIFI_CHECK_INTERVAL = 5 * 60 * 1000; // 每5分钟检查一次WiFi连接状态

// 天气更新相关变量
unsigned long lastWeatherUpdate = 0;
unsigned long lastTimeUpdate = 0;
unsigned long lastFullRefresh = 0;
unsigned long lastWiFiCheck = 0;
int lastMinute = -1;

// 重试设置
const int MAX_RETRY_ATTEMPTS = 5;  // 减少最大重试次数
const unsigned long BASE_RETRY_DELAY = 5000;  // 基础重试间隔（毫秒）

// 声明外部变量
extern WeatherInfo currentWeather;  // 在business_clock_page.cpp中定义

// 带重试机制的天气信息获取
bool getWeatherWithRetry() {
    Serial.println("开始获取天气信息（带重试机制）...");
    
    for (int attempt = 1; attempt <= MAX_RETRY_ATTEMPTS; attempt++) {
        Serial.printf("第 %d 次尝试获取天气信息...\n", attempt);
        
        if (updateWeatherInfo()) {
            Serial.printf("第 %d 次尝试成功获取天气信息\n", attempt);
            return true;
        }
        
        if (attempt < MAX_RETRY_ATTEMPTS) {
            // 使用指数退避策略计算延迟时间
            unsigned long retryDelay = BASE_RETRY_DELAY * (1 << (attempt - 1)); // 5s, 10s, 20s, 40s...
            Serial.printf("第 %d 次尝试失败，%lu 毫秒后重试...\n", attempt, retryDelay);
            delay(retryDelay);
        }
    }
    
    Serial.printf("在 %d 次尝试后仍未能获取天气信息，将使用备用数据\n", MAX_RETRY_ATTEMPTS);
    return false;
}

// 更新天气信息
bool updateWeatherInfo() {
    Serial.println("开始更新天气信息...");
    
    // 获取位置信息
    LocationInfo location = networkAPI.getLocation();
    if (!location.success) {
        Serial.println("获取位置信息失败: " + location.message);
        return false;
    }
    Serial.println("当前位置: " + location.location);
    
    // 获取行政区域信息
    AreaInfo area = networkAPI.getAreaInfo(location.location);
    if (!area.success) {
        Serial.println("获取行政区域信息失败: " + area.message);
        return false;
    }
    Serial.println("区域代码: " + area.areaCode);
    
    // 获取天气信息
    WeatherInfo weather = networkAPI.getWeather(area.areaCode);
    if (!weather.success) {
        Serial.println("获取天气信息失败: " + weather.message);
        return false;
    }
    
    // 更新全局天气信息
    currentWeather = weather;
    lastWeatherUpdate = millis();
    
    // 打印天气信息
    Serial.println("天气信息更新成功:");
    Serial.println("当前天气: " + weather.weather);
    Serial.println("温度: " + String(weather.temperature) + "°C");
    Serial.println("体感温度: " + String(weather.feelsLike) + "°C");
    Serial.println("湿度: " + String(weather.humidity) + "%");
    Serial.println("风向: " + weather.windDir);
    Serial.println("风力: " + weather.windClass);
    
    return true;
}

// 检查是否需要更新时间
bool shouldUpdateTime() {
    struct tm timeinfo;
    if (!getLocalTime(&timeinfo)) {
        return false;
    }
    
    if (lastMinute != timeinfo.tm_min) {
        lastMinute = timeinfo.tm_min;
        return true;
    }
    
    return false;
}

void setup() {
    Serial.begin(115200);
    delay(1000); // 等待串口稳定
    
    Serial.println("\n\n====================================");
    Serial.println("ESP32墨水屏天气时钟启动");
    Serial.println("====================================");

    // 初始化随机数发生器
    randomSeed(analogRead(0));
    Serial.println("随机数发生器已初始化");

    // 初始化MQTT
    initMQTT();

    // 配置API参数
    APIConfig config;
    config.areaToken = "f0694355ead336ac8cfe1cb8fd5a82bf";
    config.weatherKey = "1wSeNCJmJXF1X2biguOOEWCXJkFEjuuE";
    config.weatherUpdateInterval = WEATHER_UPDATE_INTERVAL;
    networkAPI.configure(config);
    
    // 确保WiFi连接
    Serial.println("检查WiFi连接状态...");
    if (!networkAPI.checkAndReconnectWiFi()) {
        Serial.println("WiFi连接失败，将在5秒后重试...");
        delay(5000);
        if (!networkAPI.checkAndReconnectWiFi()) {
            Serial.println("WiFi连接再次失败，继续初始化，将在运行时重试连接");
        } else {
            Serial.println("WiFi连接成功");
        }
    } else {
        Serial.println("WiFi连接成功");
    }
    
    // 初始化NTP时间同步
    Serial.println("正在初始化NTP时间同步...");
    networkAPI.initNTP();
    
    // 首次获取天气信息（带重试机制）
    Serial.println("开始首次天气信息获取...");
    if (getWeatherWithRetry()) {
        Serial.println("首次天气信息获取成功");
    } else {
        Serial.println("首次天气信息获取失败，将在下次更新时重试");
    }
    
    printf("ESP32墨水屏天气时钟初始化...\r\n");
    DEV_Module_Init();

    printf("电子纸屏初始化并清屏...\r\n");
    EPD_7IN5B_V2_Init();
    EPD_7IN5B_V2_Clear();
    DEV_Delay_ms(500);

    initPageManager();
    
    // 记录首次全屏刷新时间
    lastFullRefresh = millis();
    
    // 初始化WiFi检查时间
    lastWiFiCheck = millis();
    
    Serial.println("初始化完成");
}

void loop() {
    unsigned long currentMillis = millis();
    
    // 处理MQTT通信
    handleCommunication();
    checkTemporaryPage();
    
    // 检查是否需要更新时间显示
    if (shouldUpdateTime() && currentPage.type == PAGE_TYPE_BUSINESS_CLOCK) {
        refreshTimeOnly();
        lastTimeUpdate = currentMillis;
    }
    
    // 检查是否需要同步NTP时间
    if (!networkAPI.isTimeValid()) {
        networkAPI.syncNTPTime();
    }
    
    // 定期检查WiFi连接状态
    if (currentMillis - lastWiFiCheck >= WIFI_CHECK_INTERVAL) {
        if (networkAPI.checkAndReconnectWiFi()) {
            Serial.println("WiFi连接状态良好");
        }
        lastWiFiCheck = currentMillis;
    }
    
    // 检查是否需要更新天气信息
    if (currentMillis - lastWeatherUpdate >= WEATHER_UPDATE_INTERVAL) {
        if (getWeatherWithRetry()) {
            Serial.println("天气信息更新成功");
            // 如果当前显示的是商务时钟页面，则刷新显示
            if (currentPage.type == PAGE_TYPE_BUSINESS_CLOCK) {
                displayBusinessClockPage();
            }
        } else {
            Serial.println("天气信息更新失败，将在下次更新时重试");
        }
    }
    
    // 检查是否需要全屏刷新（每24小时进行一次全屏刷新防止残影）
    if (currentMillis - lastFullRefresh >= FULL_REFRESH_INTERVAL) {
        if (currentPage.type == PAGE_TYPE_BUSINESS_CLOCK) {
            Serial.println("执行定期全屏刷新...");
            displayBusinessClockPage();
            lastFullRefresh = currentMillis;
        }
    }
    
    delay(1000); // 每秒检查一次
}